package cn.springmvc.noconfig.initializer;

import cn.springmvc.noconfig.config.MvcConfig;
import org.springframework.core.Conventions;
import org.springframework.util.Assert;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import java.util.EnumSet;

/**
 * ClassName: WebInitializer2
 * Desc: 初始化类，代替 web.xml配置,可以处理原生的处理
 * Date： 2017/5/4
 * Created：shaom
 */
public class WebInitializer2 extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{MvcConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }


    /*以上是必须的，以下是可选的*/

    /**
     * 添加 Filter
     *
     * @return
     */
    @Override
    protected Filter[] getServletFilters() {
        return super.getServletFilters();
        /*CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setBeanName("characterEncodingFilter");
        return new Filter[]{characterEncodingFilter};*/
    }

    /**
     * 注册filter,如果需要配置 url-pattern 需要重写,可以放入 ServletConfig
     *
     * @param servletContext
     * @param filter
     * @return
     */
    @Override
    protected FilterRegistration.Dynamic registerServletFilter(ServletContext servletContext, Filter filter) {

        return super.registerServletFilter(servletContext, filter);
//        return registerFilter(servletContext, filter);
    }

    private FilterRegistration.Dynamic registerFilter(ServletContext servletContext, Filter filter) {
        String filterName = Conventions.getVariableName(filter);
        FilterRegistration.Dynamic registration = servletContext.addFilter(filterName, filter);
        if (registration == null) {
            int counter = -1;
            while (counter == -1 || registration == null) {
                counter++;
                registration = servletContext.addFilter(filterName + "#" + counter, filter);
                Assert.isTrue(counter < 100,
                        "Failed to register filter '" + filter + "'." +
                                "Could the same Filter instance have been registered already?");
            }
        }

        registration.setAsyncSupported(isAsyncSupported());
        registration.addMappingForUrlPatterns(getDispatcherTypes(), false, servletContext.getInitParameter(filterName));
        return registration;
    }

    private EnumSet<DispatcherType> getDispatcherTypes() {
        return isAsyncSupported() ?
                EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ASYNC) :
                EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE);
    }
}
